package com.juqimiao.outposts.spring.oauth2.api.services;

import com.juqimiao.outposts.spring.oauth2.api.services.dto.OAuthClientDetails;
import com.nimbusds.oauth2.sdk.GrantType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 管理客户信息的类。
 */
@Service(value = "OAuthClientDetailServiceImpl")
public class OAuthClientDetailServiceImpl implements ClientDetailsService {

    private List<OAuthClientDetails> oAuthClientDetailsList;


    private BCryptPasswordEncoder encoderl;

    /**
     * 构造函数
     */
    public OAuthClientDetailServiceImpl() {
        encoderl = new BCryptPasswordEncoder();
        initialClients();
    }

    /**
     * 通过client Id 尝试加载一个client 信息.
     *
     * @param clientId 客户标识.
     * @return 客户端信息  {@link ClientDetails }
     * @throws ClientRegistrationException
     */
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {

        //需要添加Cache机制
        if (clientId == null) {
            throw new ClientRegistrationException("Client don't exist");
        }

        return oAuthClientDetailsList.stream().filter(client -> client.getClientId().equals(clientId)).findFirst().get();
    }

    private void initialClients() {
        oAuthClientDetailsList = new ArrayList<>();
        List<String> scope = new ArrayList<>();
        scope.add("system");
        scope.add("user");
        List<String> resources1 = new ArrayList<>();
        resources1.add("outposts-resource-api");

        List<String> resources2 = new ArrayList<>();
        resources2.add("outposts-spring-oauth2-api");
        resources2.add("outposts-resource-api");

        List<String> resources3 = new ArrayList<>();


        List<GrantedAuthority> authorities1 = new ArrayList<>();
        GrantedAuthority authority1 = new SimpleGrantedAuthority("USER");
        authorities1.add(authority1);

        List<String> types = new ArrayList<>();

        //非要在这里明确指定每个client都具有怎么样的认证方式。
        types.add(GrantType.PASSWORD.getValue());
        types.add(GrantType.REFRESH_TOKEN.getValue());
        types.add(GrantType.CLIENT_CREDENTIALS.getValue());
        types.add(GrantType.AUTHORIZATION_CODE.getValue());
        types.add(GrantType.IMPLICIT.getValue());
        types.add("mobile");

        for (int i = 1; i <= 2; i++) {
            OAuthClientDetails client = new OAuthClientDetails();
            client.setClientId("demoApp" + String.valueOf(i));
            client.setClientSecret(encoderl.encode("demoAppSecret"));
            client.setScope(scope);
            client.setAuthorities(authorities1);
            client.setRefreshTokenValiditySeconds(120000);
            client.setAccessTokenValiditySeconds(500000);
            if (i == 1) {
                client.setResourceIds(resources1);
            }
            if (i == 2) {
                client.setAuthorities(new ArrayList<GrantedAuthority>());
                client.setResourceIds(resources2);
            }


            client.setAuthorizedGrantTypes(types);
            oAuthClientDetailsList.add(client);
        }
    }
}
